﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using DrawingCurveDT2.Controls;
using System.IO;
using Novacast.Thermal;

namespace DrawingCurveDT2
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }


        #region Internal

        void DoTheDrawing(List<double> TestList)
        {
            mainDG.Children.Clear();
            if (TestList.Count == 0) return;
            //for (int i = 0; i < mainDG.Children.Count(); i++)
            //    mainDG.Children.RemoveAt(i);


            CurveDrawer curveDrawer = new CurveDrawer() { Size = new Size(300, 300), Pen = new Pen(Brushes.Red, 2), Background = Brushes.Transparent, ScaleX = 2 };
            List<Point> curvePoints = new List<Point>();
            for (int i = 0; i < TestList.Count; i++)
                curvePoints.Add(new Point(i, TestList[i] - 1000d));
            curveDrawer.Points = curvePoints;
            mainDG.Children.Add(curveDrawer.DrawingGroup);


            #region Derivatives
            List<Point> Der1Points = Derivate(curvePoints, 1);
            List<Point> Der2Points = Derivate(Der1Points, 2);
            List<Point> Der3Points = Derivate(Der2Points, 3);
            List<Point> Der4Points = Derivate(Der3Points, 4);
            List<Point> Der5Points = Derivate(Der4Points, 5);
            List<Point> Der6Points = Derivate(Der5Points, 6);
            List<Point> Der7Points = Derivate(Der6Points, 7);
            List<Point> Der8Points = Derivate(Der7Points, 8);
            List<Point> Der9Points = Derivate(Der8Points, 9);

            CurveDrawer Der1Drawer = new CurveDrawer() { Pen = new Pen(Brushes.Green, 1), ScaleX = 2, ScaleY = 40 }; Der1Drawer.Points = Der1Points;
            CurveDrawer Der2Drawer = new CurveDrawer() { Pen = new Pen(Brushes.Blue, 1), ScaleX = 2, ScaleY = 600 }; Der2Drawer.Points = Der2Points;
            CurveDrawer Der3Drawer = new CurveDrawer() { Pen = new Pen(Brushes.Black, 1), ScaleX = 2, ScaleY = 1000 }; Der3Drawer.Points = Der3Points;
            CurveDrawer Der4Drawer = new CurveDrawer() { Pen = new Pen(Brushes.Violet, 1), ScaleX = 2, ScaleY = 10000 }; Der4Drawer.Points = Der4Points;

            mainDG.Children.Add(Der1Drawer.DrawingGroup);
            mainDG.Children.Add(Der2Drawer.DrawingGroup);
            //mainDG.Children.Add(Der3Drawer.DrawingGroup);
            //mainDG.Children.Add(Der4Drawer.DrawingGroup); 
            #endregion

            #region Testing1
            ////Zero test
            //foreach (Point p in Der1Points)
            //    if (p.Y >= -0.01 && p.Y <= 0.01)
            //        curveDrawer.PlacePoint((int)p.X, "1");

            //foreach (Point p in Der2Points)
            //    if (p.Y >= -0.001 && p.Y <= 0.001)
            //        curveDrawer.PlacePoint((int)p.X, "2");

            //foreach (Point p in thirdDerPoints)
            //    if (p.Y >= -0.00001 && p.Y <= 0.00001)
            //        curveDrawer.PlacePoint((int)p.X, "3");

            ////foreach (Point p in fourthDerPoints)
            ////    if (p.Y >= -0.000001 && p.Y <= 0.000001)
            ////        curveDrawer.PlacePoint((int)p.X, "4");

            ////Maxima/Minima test
            //curveDrawer.PlacePoint(MaxIndex(Der1Points), "max1- " + MaxIndex(Der1Points).ToString());
            //curveDrawer.PlacePoint(MinIndex(Der1Points), "min1- " + MinIndex(Der1Points).ToString());

            //curveDrawer.PlacePoint(MaxIndex(Der2Points), "max2- " + MaxIndex(Der2Points).ToString());
            //curveDrawer.PlacePoint(MinIndex(Der2Points), "min2- " + MinIndex(Der2Points).ToString());
            //curveDrawer.PlacePoint(MaxIndex(Der3Points), "max3- " + MaxIndex(Der3Points).ToString());
            //curveDrawer.PlacePoint(MinIndex(Der3Points), "min3- " + MinIndex(Der3Points).ToString());
            //curveDrawer.PlacePoint(MaxIndex(Der4Points), "max4- " + MaxIndex(Der4Points).ToString());
            //curveDrawer.PlacePoint(MinIndex(Der4Points), "min4- " + MinIndex(Der4Points).ToString());
            //curveDrawer.PlacePoint(MaxIndex(Der5Points), "max5- " + MaxIndex(Der5Points).ToString());
            //curveDrawer.PlacePoint(MinIndex(Der5Points), "min5- " + MinIndex(Der5Points).ToString());
            //curveDrawer.PlacePoint(MaxIndex(Der6Points), "max6- " + MaxIndex(Der6Points).ToString());
            //curveDrawer.PlacePoint(MinIndex(Der6Points), "min6- " + MinIndex(Der6Points).ToString());
            //curveDrawer.PlacePoint(MaxIndex(Der7Points), "max7- " + MaxIndex(Der7Points).ToString());
            //curveDrawer.PlacePoint(MinIndex(Der7Points), "min7- " + MinIndex(Der7Points).ToString());
            //curveDrawer.PlacePoint(MaxIndex(Der8Points), "max8- " + MaxIndex(Der8Points).ToString());
            //curveDrawer.PlacePoint(MinIndex(Der8Points), "min8- " + MinIndex(Der8Points).ToString());

            #endregion

            PlaceSignificatPoints(Der1Points, Der1Drawer, curveDrawer, "1");
            PlaceSignificatPoints(Der2Points, Der2Drawer, curveDrawer, "2");

            //bool up = true, down = true;
            //List<Point> point; CurveDrawer drawer;
            //int prevSign = 1, currSign = 1;
            //bool updateSign = false;

            //point = Der1Points; drawer = Der1Drawer;
            //for (int i = 7 + 1; i < point.Count - 7 - 1; i++)
            //{
            //    double prev = point[i - 1].Y;
            //    double curr = point[i].Y;
            //    double next = point[i + 1].Y;

            //    if (prev < curr)
            //    {
            //        if (down)
            //        {
            //            drawer.PlacePoint(i - 1, "v");
            //            //curveDrawer.PlacePoint(i - 1, "v");
            //        }
            //        down = false; up = true;
            //    }

            //    if (prev > curr)
            //    {
            //        if (up)
            //        {
            //            drawer.PlacePoint(i - 1, "^");
            //            //   curveDrawer.PlacePoint(i - 1, "^");
            //        }
            //        up = false; down = true;
            //    }

            //    if (curr > 0)
            //    {
            //        if (prevSign != currSign && prevSign == -1)
            //            updateSign = true;

            //        prevSign = currSign;
            //        currSign = 1;
            //    }
            //    else if (curr < 0)
            //    {
            //        if (prevSign != currSign && prevSign == 1)
            //            updateSign = true;

            //        prevSign = currSign;
            //        currSign = -1;
            //    }

            //    if (updateSign)
            //    {
            //        if (currSign == 1) curveDrawer.PlacePoint(i - 1, "=> +");
            //        if (currSign == -1) curveDrawer.PlacePoint(i - 1, "=> -");
            //        updateSign = false;
            //    }

            //}

            //point = curvePoints; drawer = curveDrawer;
            //for (int i = 0 + 1; i < point.Count - 1; i++)
            //{
            //    break;
            //    double prev = point[i - 1].Y;
            //    double curr = point[i].Y;
            //    double next = point[i + 1].Y;

            //    if (prev < curr)
            //    {
            //        if (down)
            //        {
            //            int firstPos = i - 1;
            //            for (int j = i - 1; i > 1; j--)
            //            {
            //                if (point[j].Y != prev) break;
            //                firstPos = j;
            //            }
            //            int pos = (int)((firstPos + i - 1) / 2);

            //            curveDrawer.PlacePoint(pos, "v - " + (point[i - 1].Y + 1000).ToString());
            //        }
            //        down = false; up = true;
            //    }

            //    if (prev > curr)
            //    {
            //        if (up)
            //        {
            //            int firstPos = i - 1;
            //            for (int j = i - 1; i > 1; j--)
            //            {
            //                if (point[j].Y != prev) break;
            //                firstPos = j;
            //            }
            //            int pos = (int)((firstPos + i - 1) / 2);

            //            curveDrawer.PlacePoint(pos, "^ - " + (point[i - 1].Y + 1000).ToString());
            //        }
            //        up = false; down = true;
            //    }

            //}


            //for (int i = 14; i < Der2Points.Count - 14; i++)
            //{
            //    bool before1 = Der2Points[i - 1].Y > 0;
            //    bool before2 = Der2Points[i - 2].Y > 0;
            //    bool after1 = Der2Points[i + 1].Y < 0;
            //    bool after2 = Der2Points[i + 2].Y < 0;
            //    if (before2 && before1 && after1 && after2)
            //    {
            //        //curveDrawer.PlacePoint(i, "TL: " + (1000 + curvePoints[i].Y).ToString("####"));
            //        curveDrawer.PlacePoint(i, "C2");
            //    }
            //}


        }

        private void PlaceSignificatPoints(List<Point> Points, CurveDrawer Drawer, CurveDrawer curveDrawer, string Label)
        {
            bool up = true, down = true;
            List<Point> point; CurveDrawer drawer;
            int prevSign = 1, currSign = 1;
            bool updateSign = false;

            point = Points; drawer = Drawer;
            for (int i = 7 + 1; i < point.Count - 7 - 1; i++)
            {
                double prev = point[i - 1].Y;
                double curr = point[i].Y;
                double next = point[i + 1].Y;

                if (prev < curr)
                {
                    if (down)
                    {
                        drawer.PlacePoint(i - 1, "v");
                        //curveDrawer.PlacePoint(i - 1, "v");
                    }
                    down = false; up = true;
                }

                if (prev > curr)
                {
                    if (up)
                    {
                        drawer.PlacePoint(i - 1, "^");
                        //   curveDrawer.PlacePoint(i - 1, "^");
                    }
                    up = false; down = true;
                }

                if (curr > 0)
                {
                    if (prevSign != currSign && prevSign == -1)
                        updateSign = true;

                    prevSign = currSign;
                    currSign = 1;
                }
                else if (curr < 0)
                {
                    if (prevSign != currSign && prevSign == 1)
                        updateSign = true;

                    prevSign = currSign;
                    currSign = -1;
                }

                if (updateSign)
                {
                    if (currSign == 1) curveDrawer.PlacePoint(i - 1, "=" + Label + "> +");
                    if (currSign == -1) curveDrawer.PlacePoint(i - 1, "=" + Label + "> -");
                    updateSign = false;
                }

            }
        }

        int MaxIndex(List<Point> points)
        {
            double max = 0;
            int index = 0;
            foreach (Point p in points)
                if (p.Y > max)
                { max = p.Y; index = (int)p.X; }

            return index;
        }

        int MinIndex(List<Point> points)
        {
            double min = 10000;
            int index = 0;
            foreach (Point p in points)
                if (p.Y < min)
                { min = p.Y; index = (int)p.X; }

            return index;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            pathTextBox.Text = @"E:\Development\Therm\calcdt1\Curves\tester";
        }

        List<Point> Derivate(List<Point> InCurve)
        {
            return Derivate(InCurve, 1);
        }
        List<Point> Derivate(List<Point> InCurve, int Level)
        {
            int step = 7 * Level;
            Point[] outCurve = new Point[InCurve.Count];


            double num, denom, FirstDer;
            for (int i = step; i <= InCurve.Count - step; i++)
            {
                num = 0;
                denom = 0;
                //Anvander allra 1:a punkten i .Temp och ar den ar inte filtrerat och det ger "konstigt" utseende pa 1:a der.
                for (int j = 1; j < step; j++)
                {
                    num = num + InCurve[i - j].Y - InCurve[i + j].Y;
                    denom = denom + InCurve[i - j].X - InCurve[i + j].X;
                }
                FirstDer = num / denom;

                Point p = new Point(i, FirstDer);
                outCurve[i] = p;
            }

            Point firstPoint = outCurve[step];
            for (int i = 0; i < step && i < outCurve.Count(); i++)
                outCurve[i] = new Point(firstPoint.X, firstPoint.Y);

            Point lastPoint = outCurve[outCurve.Count() - step];
            for (int i = outCurve.Count() - step; i < outCurve.Count() && i >= 0; i++)
                outCurve[i] = new Point(lastPoint.X, lastPoint.Y);

            return outCurve.ToList();
        }
        #endregion

        #region Testing
        private void drawButton_Click(object sender, RoutedEventArgs e)
        {
            List<double> testList = new List<double>() { 
                1274.75, 1259.45, 1249.61, 1243.77, 1238.4, 1233.17, 1228.19, 1223.07, 1218.37, 1214.01, 1210.44, 1206.91, 1203.39, 1200.21, 1196.83, 1193.53, 
                1190.64, 1188.2, 1186.17, 1184.27, 1182.8, 1181.77, 1180.79, 1180.09, 1179.56, 1179.31, 1179.07, 1179.01, 1179.01, 1179.09, 1179.04, 1179.04, 
                1179.01, 1178.94, 1178.63, 1178.24, 1177.7, 1176.96, 1176.22, 1175.28, 1174.28, 1173.28, 1172.18, 1171.08, 1170.06, 1168.95, 1167.8, 1166.73, 
                1165.67, 1164.61, 1163.46, 1162.42, 1161.46, 1160.32, 1159.3, 1158.32, 1157.34, 1156.4, 1155.47, 1154.61, 1153.85, 1153.11, 1152.23, 1151.39, 
                1150.71, 1149.98, 1149.3, 1148.65, 1147.99, 1147.41, 1146.88, 1146.37, 1145.94, 1145.49, 1145.06, 1144.71, 1144.48, 1144.15, 1143.89, 1143.67, 
                1143.5, 1143.35, 1143.26, 1143.26, 1143.18, 1143.13, 1143.13, 1143.19, 1143.25, 1143.27, 1143.3, 1143.39, 1143.46, 1143.61, 1143.71, 1143.83, 
                1144.0, 1144.16, 1144.28, 1144.47, 1144.62, 1144.78, 1144.97, 1145.22, 1145.33, 1145.47, 1145.68, 1145.87, 1145.99, 1146.11, 1146.28, 1146.4, 
                1146.53, 1146.6, 1146.74, 1146.84, 1146.91, 1146.97, 1147.03, 1147.11, 1147.2, 1147.25, 1147.3, 1147.38, 1147.39, 1147.4, 
                1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 
                1147.47, 
                1147.44, 1147.42, 1147.4, 1147.32, 1147.26, 1147.22, 1147.13, 1147.1, 1147.0, 1146.89, 1146.83, 1146.74, 1146.57, 1146.4, 1146.25, 1146.08, 
                1145.87, 1145.75, 1145.51, 1145.29, 1145.05, 1144.82, 1144.59, 1144.31, 1144.09, 1143.79, 1143.51, 1143.16, 1142.86, 1142.5, 1142.11, 1141.69,
                1141.26, 1140.81, 1140.34, 1139.81, 1139.23, 1138.6, 1137.93, 1137.15, 1136.4, 1135.24, 1134.05, 1132.73, 1131.29, 1129.55, 1127.18, 1124.26, 
                1120.6, 1116.27, 1111.22, 1105.78, 1100.92, 1096.9, 1093.56, 1090.71, 1088.02, 1085.54, 1083.3, 1081.08, 1078.91, 1076.87, 1074.84, 1072.96, 
                1071.11, 1069.32, 1067.45, 1065.73, 1063.99, 1062.27, 1060.51, 1058.83, 1057.28, 1055.53, 1053.96, 1052.31, 1050.47, 1048.8, 1047.25, 1045.62, 
                1044.03, 1042.47, 1040.94, 1039.33, 1037.81, 1036.3, 1034.75, 1033.24, 1031.72, 1030.2, 1028.83, 1027.27, 1025.81, 1024.34, 1022.75, 1021.26 };
            DoTheDrawing(testList);
        }

        private void pathTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (!Directory.Exists(pathTextBox.Text)) return;
            string[] files = Directory.GetFiles(pathTextBox.Text);
            List<FileInfo> fileInfos = new List<FileInfo>();
            foreach (string f in files)
            {
                FileInfo fi = new FileInfo(f);
                if (fi.Extension.ToLower().Contains("ku"))
                    fileInfos.Add(fi);
            }

            filesListView.ItemsSource = fileInfos;
        }
        #endregion

        private void filesListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                FileInfo fi = filesListView.SelectedItem as FileInfo;
                if (fi == null) return;

                List<double> TestList = new List<double>();
                Curve curve = new Curve();
                Novacast.InputOutput.FileMan.readCurveDataFromFile(fi.FullName, ref curve);

                for (int i = 0; i < curve.SampleSize(); i++)
                    TestList.Add(curve.SampleData[i].Temp);
                DoTheDrawing(TestList);

            }
            catch (Exception)
            {
                DoTheDrawing(new List<double>());

            }
        }

    }
}
